#include "types.h"
#include "param.h"
#include "memlayout.h"
#include "riscv.h"
#include "defs.h"
#include "spinlock.h"

static volatile int g_timer_test_count = 0;

// 包装的时钟中断处理：计数 + 调用默认 timer_interrupt()
static void timer_test_handler(void) {
  g_timer_test_count++;
  timer_interrupt(); // 保持 ticks 递增与调度钩子
}

void test_timer_interrupt(void) {
  printf("Testing timer interrupt...\n");

  // 注册测试专用 handler 并开启 SSIP
  register_interrupt(1, timer_test_handler);
  enable_interrupt(1);

  uint64 start_time = get_time();
  int target = 5;

  int last = -1;
  while (g_timer_test_count < target) {
    if (g_timer_test_count != last) {
      printf("Waiting for interrupt %d...\n", g_timer_test_count + 1);
      last = g_timer_test_count;
    }
    // 简单延时，避免刷屏
    for (volatile int i = 0; i < 100000; i++);
  }

  uint64 end_time = get_time();
  // 注意：printf 不支持 %lu，用 %p 打 64 位数
  printf("Timer test completed: %d interrupts in %p cycles\n",
         g_timer_test_count, (void*)(end_time - start_time));

  // 恢复默认时钟处理
  register_interrupt(1, timer_interrupt);
}

void test_exception_handling(void) {
  printf("Testing exception handling...\n");

  // 1) 加载页故障（访问未映射地址 0）
  (void)*(volatile uint64*)0;

  // 2) 存储页故障（写未映射地址 0）
  *(volatile uint64*)0 = 1;

  // 3) 非法指令（可安全跳过）
  asm volatile(".word 0xdeadbeef");

  printf("Exception tests completed\n");
}

void test_interrupt_overhead(void) {
  printf("Measuring interrupt/tick intervals...\n");

  uint64 t0 = get_time();

  // 不加锁读取 ticks，避免与中断中的 timer_interrupt 争用同一把锁
  uint64 start_ticks = ticks;
  uint64 target = start_ticks + 50; // 50 个 tick

  while (ticks < target) {
    // 忙等
  }

  uint64 t1 = get_time();
  uint64 delta = t1 - t0;
  printf("50 ticks took %p cycles (~%p cycles/tick)\n",
         (void*)delta, (void*)(delta / 50));
}